package us.gaaoc.framework.webapp.util;

import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import java.util.GregorianCalendar;

import javax.faces.context.FacesContext;
import javax.faces.validator.ValidatorException;
import javax.faces.webapp.FacesServlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;


import us.gaaoc.framework.model.Person;

/**
 * Custom Servlet which wraps the FacesServlet
 * for error page handling.
 * @author artripa
 *
 */
public class GajeFacesServlet extends HttpServlet {

	private static final long serialVersionUID = 1L;

	private static final String INIT_PARAM_ERROR_PAGE = "errorPage";

	private FacesServlet delegate;

	private String errorPage;

	
	
	Logger log = Logger.getLogger(GajeFacesServlet.class);
	
	public void init(ServletConfig servletConfig) throws ServletException {
		delegate = new FacesServlet();
		delegate.init(servletConfig);
		errorPage = servletConfig.getInitParameter(INIT_PARAM_ERROR_PAGE);
	}

	public void destroy() {
		delegate.destroy();
	}

	public ServletConfig getServletConfig() {
		return delegate.getServletConfig();
	}

	public String getServletInfo() {
		return delegate.getServletInfo();
	}

	public static String getUrl3(HttpServletRequest req) { String scheme = req.getScheme(); 
		String serverName = req.getServerName();
		int serverPort = req.getServerPort();  
		String contextPath = req.getContextPath(); 
		String servletPath = req.getServletPath(); 
		String pathInfo = req.getPathInfo(); 
		String queryString = req.getQueryString(); 
		String url = scheme+"://"+serverName+":"+serverPort+contextPath+servletPath; 
		if (pathInfo != null) { url += pathInfo; } if (queryString != null) { url += "?"+queryString; } return url;  
	}

	public void service(ServletRequest request, ServletResponse response)
			throws ServletException, IOException {
		try 
		{
			delegate.service(request, response);
		} 
		catch (ValidatorException exn) 
		{
			throw exn;
		} 
		catch (Throwable e) 
		{

			HttpServletRequest req = (HttpServletRequest) request;					
			req.getSession().setAttribute("gaje.exception",e);
								
			/*
			 * Here we should 
			 * 	1) print username
			 *  2) print sessionMap
			 *  3) print URL 
			 *  4) print viewID
			 *  5) generate a UUID
			 *  6) notify the end user?
			 */
			
			Calendar c = new GregorianCalendar();
			c.setTime(new Date());
			
			String username = "";
			if(req.getSession().getAttribute("person") != null)
				username = ((Person)req.getSession().getAttribute("person")).getUserId();
			
			
			
			String errortrackingid =
				String.format("%s%s%s%s%s%s",
						c.get(Calendar.YEAR),
						c.get(Calendar.MONTH+1),
						c.get(Calendar.DAY_OF_MONTH),
						username,
						c.get(Calendar.HOUR_OF_DAY),
						c.get(Calendar.SECOND));
			
			req.getSession().setAttribute("gaje.errorTrackingId",errortrackingid);
			

			
			log.warn("500 ERROR");			
			log.error("\t:errortrackingid", e);
			log.warn("\tErrorID: " + errortrackingid);
			log.warn("\tUsername: " + username);
			log.warn("\tURL: " + getUrl3(req));
			log.warn("\tMethod: " + req.getMethod());
			log.warn("\tSession: ");
			Enumeration keys = req.getSession().getAttributeNames();
			for(String key = null;keys.hasMoreElements();key = (String) keys.nextElement())
			{
				if(key != null && !key.equals("personOrgs"))
				{
					log.warn(String.format("\t\t%s : %s",key,req.getSession().getAttribute(key)));
				}
			}
			
			log.warn("\tURL : " + req.getRequestURI());
			//log.warn("\tVIEWID: " + FacesContext.getCurrentInstance().getViewRoot().getViewId());
			log.warn("END ERROR");
														
			redirectToErrorPage((HttpServletRequest) request,
					(HttpServletResponse) response);
		}
	}

	private void redirectToErrorPage(HttpServletRequest request,
			HttpServletResponse response) throws IOException {
		if ( errorPage != null && !"".equals(errorPage)) 
		{
			response.sendRedirect(request.getContextPath() + errorPage);
		}
	}

}
